
package com.xpo.settingskeeper;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import java.util.ArrayList;

public abstract class SettingsKeeper {

    protected static final int WORK_DB_VERSION = 1;

    protected Context mContext = null;

    protected ArrayList<String> mSettingNameList = null;

    protected ArrayList<ContentValues> mSettingList = new ArrayList<ContentValues>();

    protected ArrayList<NameValuePair> mNameValueList = new ArrayList<NameValuePair>();

    protected SettingsDBHelper mDatabaseHelper;

    private String mDbName = null;

    public SettingsKeeper(Context context, String dbName) {
        mContext = context;
        mDbName = dbName;
        loadSettingsNameList();
    }

    public void backup() {
        readSettingsFromSystem();
        writeSettingsToDatabase(getTableName());
    }

    protected void readSettingsFromSystem() {
        if (mSettingNameList != null) {
            for (String name : mSettingNameList) {
                String value = settingItem(name);
                ContentValues contentValues = new ContentValues();
                contentValues.put(android.provider.Settings.NameValueTable.NAME, name);
                contentValues.put(android.provider.Settings.NameValueTable.VALUE, value);
                mSettingList.add(contentValues);
            }
        }
    }

    protected void writeSettingsToDatabase(String tableName) {
        mDatabaseHelper = new SettingsDBHelper(mContext, getDbName(), null, WORK_DB_VERSION);
        if (mDatabaseHelper == null) {
            return;
        }
        mDatabaseHelper.createTable(tableName);

        try {
            SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
            if (mSettingList != null && mSettingList.size() > 0) {
                for (ContentValues contentValues : mSettingList) {
                    Log.i(getTag(), "writeSettingsToDatabase():" + tableName
                            + contentValues.toString());
                    db.insert(tableName, android.provider.Settings.NameValueTable.NAME,
                            contentValues);
                }
            }
        } catch (SQLException se) {
            Log.e(getTag(), se.toString());
        }

        if (mDatabaseHelper != null) {
            mDatabaseHelper.close();
            mDatabaseHelper = null;
        }
    }

    public void restore() {
        readSettingsFromDatabase();
        writeSettingsToSystem();
    }

    private void readSettingsFromDatabase() {
        mDatabaseHelper = new SettingsDBHelper(mContext, getDbName(), null, WORK_DB_VERSION);
        if (mDatabaseHelper == null) {
            return;
        }

        Cursor cur = null;
        try {
            SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();
            cur = db.query(getTableName(), new String[] {
                    android.provider.Settings.NameValueTable.NAME,
                    android.provider.Settings.NameValueTable.VALUE
            }, null, null, null, null, null);
        } catch (SQLException se) {
            Log.i(getTag(), se.toString());
        }

        if (cur != null) {
            if (mNameValueList == null) {
                mNameValueList = new ArrayList<NameValuePair>();
            }

            cur.moveToFirst();
            while (!cur.isAfterLast()) {
                NameValuePair nvp = new NameValuePair(cur.getString(0), cur.getString(1));
                mNameValueList.add(nvp);
                cur.moveToNext();
            }
            cur.close();
        }

        if (mDatabaseHelper != null) {
            mDatabaseHelper.close();
            mDatabaseHelper = null;
        }
    }

    private void writeSettingsToSystem() {
        if (mNameValueList != null) {
            ContentResolver cr = mContext.getContentResolver();
            for (NameValuePair nvp : mNameValueList) {
                Log.i(getTag(), nvp.toString());
                try {
                    setSettingItem(cr, nvp.getName(), nvp.getValue());
                } catch (Exception ex) {
                    Log.e(getTag(), ex.toString());
                }
            }

            mNameValueList = null;
        }
    }

    protected String getDbName() {
        return mDbName;
    }

    protected abstract void loadSettingsNameList();

    protected abstract String getTag();

    protected abstract String settingItem(String name);

    protected abstract boolean setSettingItem(ContentResolver resolver, String name, String value);

    protected abstract String getTableName();

}
